package org.ms.mtx.core.context;

import lombok.*;
import org.ms.mtx.core.TransactionStatus;

import java.io.Serializable;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * The Transaction Context
 *
 * @author lry
 */
@Data
@ToString
public class TransactionContext implements Serializable {

    /**
     * The request id
     */
    private String id;
    /**
     * The transaction id
     */
    private String txId;
    /**
     * The transaction cancel is asynchronous
     */
    private Boolean async;
    /**
     * The transaction status
     */
    private TransactionStatus status;
    /**
     * The retry times
     */
    private volatile Integer retriedTimes;
    /**
     * The create time
     */
    private Long createTime;
    /**
     * The last update time
     */
    private Long lastUpdateTime;
    /**
     * The transaction attributes
     */
    private Map<String, Object> attributes = new HashMap<>();

    /**
     * The sub transaction list, the must be use {@link LinkedHashMap}
     */
    private Map<String, MethodInvokeContext> cancels = new LinkedHashMap<>();

    /**
     * The copy cancels
     *
     * @return {@link Map}
     */
    public Map<String, MethodInvokeContext> copyCancels() {
        Map<String, MethodInvokeContext> tempCancels = new LinkedHashMap<>();
        if (cancels.isEmpty()) {
            return tempCancels;
        }

        for (Map.Entry<String, MethodInvokeContext> entry : cancels.entrySet()) {
            MethodInvokeContext mic = entry.getValue();
            MethodInvokeContext methodInvokeContext = MethodInvokeContext.builder()
                    .beanObject(mic.getBeanObject())
                    .methodName(mic.getMethodName())
                    .parameterTypes(mic.getParameterTypes())
                    .parameters(mic.getParameters()).build();
            tempCancels.put(entry.getKey(), methodInvokeContext);
        }

        return tempCancels;
    }

}
